package work.soho.proxy;

import com.aliyuncs.exceptions.ClientException;
import work.soho.proxy.aliyun.parts.AliyunPartsException;
import work.soho.proxy.aliyun.parts.DdnsLanPart;
import work.soho.proxy.aliyun.parts.DdnsWanPart;
import work.soho.proxy.aliyun.parts.PartsManage;
import work.soho.proxy.component.IComponent;
import work.soho.proxy.component.impl.DomainImpl;
import work.soho.proxy.component.impl.JavaSocket5Impl;
import work.soho.proxy.component.impl.ProxySocket5Impl;

import java.io.IOException;
import java.net.Socket;
import java.util.HashMap;

public class ProxyDaemon {
   private ConfigManage configManage;

    /**
     * proxy，register 检查线程
     */
    private Thread checkThread = null;

    private HashMap<String, IComponent> componentHashMap = new HashMap<>();

    public ConfigManage getConfigManage() {
        return configManage;
    }

    public void setConfigManage(ConfigManage configManage) {
        this.configManage = configManage;
    }

    /**
     * 获取检查线程
     *
     * @return
     */
    public Thread getCheckThread() {
        return checkThread;
    }

    /**
     * 获取组件
     *
     * @param component
     * @return
     */
    private IComponent getComponent(Class<?> component) {
        if(componentHashMap.get(component.getName()) == null) {
            try {
                componentHashMap.put(component.getName(), (IComponent) component.newInstance());
            } catch (Exception e) {
                //ignore
            }
        }
        return componentHashMap.get(component.getName());
    }

    /**
     * 开启定时检查
     */
    public void check() {
        if(checkThread == null) {
            System.out.println("开启检查线程");
            checkThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    Integer ts = 5;
                    do {
                        if(ts>=0) {
                            int count=0, runCount=0;
                            System.out.println("执行例行检查");
                            //检查执行socket5
                            try {
                                if(configManage.getPartsConfigure().getUseSocket5()) {
                                    count++;
                                    System.out.println("socket5 状态检查");
                                    if(!isPortUsed()) {
                                        getComponent(JavaSocket5Impl.class).start();
                                    }
                                    runCount++;
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }

                            try {
                                //检查执行ddns
                                if(configManage.getPartsConfigure().getUseDdns()) {
                                    count++;
                                    new DomainImpl().start();
                                    runCount++;
                                }
                            } catch (Exception e) {

                            }

                            //确定图标颜色
                            if(count == runCount) {
                                ProxyApplication.switchIcon("green");
                            }
                            if(count!=0 && count>runCount) {
                                //ignore
                            }
                            if(count!=0 && runCount==0) {
                                ProxyApplication.switchIcon("red");
                            }
                        }
                        //延时处理， 防止频繁检查消耗过多的cpu
                        try {
                            ts = getConfigManage().getPartsConfigure().getAutoCheckTs();
                            Thread.sleep(ts * 1000);
                        } catch (IOException e) {
                            e.printStackTrace();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    } while (true);
                }
            });
            checkThread.start();
        }

    }

    /**
     * 切换服务器
     */
    public void switchService() throws AliyunPartsException, InterruptedException, ClientException, IOException {
        PartsManage.switchServer();
        check();
    }

    /**
     * 删除服务器
     */
    public void dropServer() {
        PartsManage.dropServer();
    }

    /**
     * 获取远程ddns ip地址
     *
     * @return
     */
    public String getDdnsLanIp() {
        return ((DdnsLanPart)PartsManage.getPartByName(DdnsLanPart.class.getName())).getDnsLanRecode().getValue();
    }

    /**
     * 获取广域网IP地址
     *
     * @return
     */
    public String getDdnsWanIp() {
        return ((DdnsWanPart)PartsManage.getPartByName(DdnsWanPart.class.getName())).getDnsLanRecode().getValue();
    }

    /**
     * 检查守护端口是否在使用
     *
     * @return
     */
    public boolean isPortUsed() {
        try {
            Socket socket = new Socket("127.0.0.1", Integer.parseInt(configManage.getPartsConfigure().getProxyPort()));
            socket.close();
            return true;
        } catch (IOException e) {
          //  e.printStackTrace();
            //ignore
        }
        return false;
    }
}
